//+------------------------------------------------------------------+
//|                                             RideTheLightning.mq4 |
//|                                                   RonaldSidharta |
//|                                                                  |
//+------------------------------------------------------------------+
#include <stdlib.mqh>

#property copyright "RonaldSidharta"
#property link      ""
datetime currentBarTime;
int magicNumber = 12163; 
int longOrderTicket = -1;
int shortOrderTicket = -1;
double longOrderClosePoint = -1000000;
double shortOrderClosePoint = 1000000;

extern int howManyBarsBefore = 2;
extern int trailingPNLPoint = 2;
extern double volume = 0.1;




int TradeBookingFunction( int command, double volume, double price, double stopLossPrice, double takeProfitPrice, int magicNumber, string comment )
{
   color arrowColor;
   RefreshRates();
   if( command == OP_BUY )
        arrowColor = LimeGreen;
   else
        arrowColor = FireBrick;
   int ticketNumber = OrderSend( Symbol(), command, volume, price, 3, 0, 0, comment, magicNumber, 0, arrowColor);
   if( ticketNumber < 1 )
   {
      int error=GetLastError();
      Print( "cannot book trade " + ErrorDescription( error ) );
   }   
   else
   {
      if( stopLossPrice == 0 && takeProfitPrice == 0 )
         return( ticketNumber );
         
      if( OrderModify( ticketNumber, 0, stopLossPrice, takeProfitPrice, 0, arrowColor ) == true )
      {
            Print( "Order placed. Ticket= " + ticketNumber );
            
            //if(command == OP_BUY)
            return( ticketNumber );      
            
            
      }   
      else
      {
            error=GetLastError();
            Print( "Failed to modify trade. " + ErrorDescription( error ) );
      }
      return(-1);
   }
}

bool TradeClosingFunction( int ticketNumber, double volume, double closingPrice, int slippage )
{
   bool RV = OrderClose( ticketNumber, volume, closingPrice, slippage );
   if( RV == true )
      return( true );
   else  
   {
      int error = GetLastError();
      Print( "Failed to close trade. " + ErrorDescription( error ) );
   }   
   return( false );    
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   Print( "initing RideTheLightning in " + Symbol() );
   Print( "I am now Riding The Lightning. Good Luck, Sir" );
   currentBarTime = Time[0];
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   string trendName; //bull or bear
   datetime tickedBarTime = Time[0]; //the opening time of the bar that just ticked
   double ClosingPrice;
   if( tickedBarTime > currentBarTime )
   {
      Print( "just opened a new bar, calculating...." );
      currentBarTime = tickedBarTime; //reset to be the same
      
      if( longOrderTicket > 0 )
      {
         if( Close[1] < longOrderClosePoint ) //if the bar that just closed, closed lower than the limit
         {
            Print( "Bar that just closed: " + Close[1] + " and longOrderClosePoint: " + longOrderClosePoint + ". Going to close long order: " + longOrderTicket );
            ClosingPrice = Bid;
            if( TradeClosingFunction( longOrderTicket, volume, ClosingPrice, 3 ) == true )
               longOrderTicket = -1;
         }   
      }
      if( shortOrderTicket > 0 )
      {
         if( Close[1] > shortOrderClosePoint ) //if the bar that just closed, closed higher than the limit
         {
            Print( "Bar that just closed: " + Close[1] + " and shortOrderClosePoint: " + shortOrderClosePoint +  ". Going to close short order: " + shortOrderTicket );
            ClosingPrice = Ask;
            if( TradeClosingFunction( shortOrderTicket, volume, ClosingPrice, 3 ) == true )
               shortOrderTicket = -1;
         }
      }          
      
      
      //inspect if the previous x bars is trending
      //AND current bar is still trending
      for(int i=howManyBarsBefore;i>0; i--)
      {
         double openVar = Open[i];
         double closeVar = Close[i];
         double diff = closeVar - openVar;
         if( i==howManyBarsBefore ) //the first time it is looping
         {
            if( diff >= 0 )
               trendName = "bull";
            else  
               trendName = "bear";
         }
         else
         {
            if( trendName == "bull" && diff < 0 )
            {
               Print( "no more bull pattern" );
               return(0);
            }
            else if( trendName ==  "bear" && diff > 0 )
            {
               Print( "no more bear pattern" );
               return(0);
            }
         }       
      }     
      int ticketNumber;
      int command;
      double price, stopLossPrice, takeProfitPrice, oldClosePoint;
      string comment;
      //if we found a bull trending, we have to make sure that current Bid is equal or higher than previous close price
      if( trendName == "bull" /*&& Ask >= Close[1]*/ )  
      { 
         //Alert( "Bid= ", Bid, ", Close= ", Close[1] );
         command = OP_BUY;
         price = Ask;   
         Print("going to book bull");
         oldClosePoint = longOrderClosePoint;
         longOrderClosePoint = Close[trailingPNLPoint];
         comment = "RideTheLightning: Bull:" + longOrderClosePoint;
         if( longOrderTicket > 0 )
         {
            Print( "There is already an active long order: " + longOrderTicket );
            Print( "We are updating the longOrderClosePoint to: " + longOrderClosePoint + " from: " + oldClosePoint );
            return( 0 );
         }   
      }   
      else if( trendName == "bear" /*&& Bid <= Close[1] */ )
      {
         //Alert( "Ask= ", Ask, ", Close= ", Close[1] );
         command = OP_SELL;
         price = Bid;
         Print("going to book bear");
         oldClosePoint = shortOrderClosePoint;
         shortOrderClosePoint = Close[trailingPNLPoint];
         comment = "RideTheLightning: Bear:" + shortOrderClosePoint;
         if( shortOrderTicket > 0 )
         {
            Print( "There is already an active short order: " + shortOrderTicket );
            Print( "We are updating the shortOrderClosePoint to: " + shortOrderClosePoint + " from: " + oldClosePoint );
            return( 0 );
         }
      }   
      else
      {
         Print( "was trending but when new bar opened, the trend broke, so we didnt book a trade" );
         return(0);
      }
      
         
      RefreshRates();
      ticketNumber = TradeBookingFunction( command, volume, price, 0, 0, magicNumber, comment );
      if( ticketNumber > 0 )
      {
         if( command == OP_BUY )
            longOrderTicket = ticketNumber;
         else if( command == OP_SELL )
            shortOrderTicket = ticketNumber;
      }
      
   }     
//----
   return(0);
  }
//+------------------------------------------------------------------+